---
import ConfigCarrier from "@components/layout/ConfigCarrier.astro";
import FontManager from "@components/interactive/FontManager.astro";
import MusicPlayer from "@components/widget/MusicPlayer.svelte";
import SakuraEffect from "@components/effects/SakuraEffect.astro";
import FancyboxManager from "@components/effects/FancyboxManager.astro";

import { profileConfig, siteConfig } from "@/config";
import {
	BANNER_HEIGHT,
	BANNER_HEIGHT_EXTEND,
	BANNER_HEIGHT_HOME,
	PAGE_WIDTH,
} from "@/constants/constants";
import { defaultFavicons } from "@/constants/icon";
import type { Favicon } from "@/types/config";
import { url } from "@/utils/url-utils";
import { getDefaultBackground, isHomePage } from "@/utils/layout-utils";

import "katex/dist/katex.css";
import "@/styles/navbar-unified.css";
import "@/styles/fancybox-custom.css";
import "@/styles/layout-styles.css";
import "@/styles/waves.css";

interface Props {
	title?: string;
	banner?: string;
	description?: string;
	lang?: string;
	setOGTypeArticle?: boolean;
	postSlug?: string;
}

let { title, banner, description, lang, setOGTypeArticle, postSlug } =
	Astro.props;

// apply a class to the body element to decide the height of the banner, only used for initial page load
// Swup can update the body for each page visit, but it's after the page transition, causing a delay for banner height change
// so use Swup hooks instead to change the height immediately when a link is clicked
const isHomePageCheck = isHomePage(Astro.url.pathname);

// defines global css variables
// why doing this in Layout instead of GlobalStyles: https://github.com/withastro/astro/issues/6728#issuecomment-1502203757
const configHue = siteConfig.themeColor.hue;

// 获取导航栏透明模式配置
const navbarTransparentMode =
	siteConfig.backgroundWallpaper?.banner?.navbar?.transparentMode || "semi";
// 判断是否应该显示顶部高光效果（只在full和semifull模式下显示）
const shouldShowTopHighlight =
	navbarTransparentMode === "full" || navbarTransparentMode === "semifull";

if (!banner || typeof banner !== "string" || banner.trim() === "") {
	banner = getDefaultBackground();
}

// TODO don't use post cover as banner for now
banner = getDefaultBackground();

const enableBanner = siteConfig.backgroundWallpaper.mode === "banner";

let pageTitle: string;
if (title) {
	pageTitle = `${title} - ${siteConfig.title}`;
} else {
	pageTitle = siteConfig.subtitle
		? `${siteConfig.title} - ${siteConfig.subtitle}`
		: siteConfig.title;
}

let ogImageUrl: string | undefined;
if (siteConfig.generateOgImages && postSlug) {
	ogImageUrl = new URL(`/og/${postSlug}.png`, Astro.site).toString();
}

const favicons: Favicon[] =
	siteConfig.favicon.length > 0 ? siteConfig.favicon : defaultFavicons;

// const siteLang = siteConfig.lang.replace('_', '-')
if (!lang) {
	lang = `${siteConfig.lang}`;
}
const siteLang = lang.replace("_", "-");

// 使用固定的banner偏移量，position配置用于图片定位
const bannerOffset = `${BANNER_HEIGHT_EXTEND / 2}vh`;

---

<!DOCTYPE html>
<html lang={siteLang} class="bg-[var(--page-bg)] text-[14px] md:text-[16px]">
	<head>
		<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-KRX3XGVH');</script>
		<script type="text/javascript">(function(c,l,a,r,i,t,y){c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);})(window, document, "clarity", "script", "tjr3vkhj8i");</script>

		<title>{pageTitle}</title>

		<meta charset="UTF-8" />
		<meta name="description" content={description || siteConfig.description || pageTitle}>
		{siteConfig.keywords && siteConfig.keywords.length > 0 && (
			<meta name="keywords" content={siteConfig.keywords.join(', ')} />
		)}
		<meta name="author" content={profileConfig.name}>

		<meta property="og:site_name" content={siteConfig.title}>
		<meta property="og:url" content={Astro.url}>
		<meta property="og:title" content={pageTitle}>
		<meta property="og:description" content={description || siteConfig.description || pageTitle}>
		{ogImageUrl && <meta property="og:image" content={ogImageUrl} />}
		{
			setOGTypeArticle ? (
				<meta property="og:type" content="article" />
			) : (
				<meta property="og:type" content="website" />
			)
		}

		<meta name="twitter:card" content="summary_large_image">
		<meta property="twitter:url" content={Astro.url}>
		<meta name="twitter:title" content={pageTitle}>
		<meta name="twitter:description" content={description || siteConfig.description || pageTitle}>

		<meta name="viewport" content="width=device-width" />
		<meta name="generator" content={Astro.generator} />
		{favicons.map(favicon => (
			<link rel="icon"
				  href={favicon.src.startsWith('/') ? url(favicon.src) : favicon.src}
				  sizes={favicon.sizes}
				  media={favicon.theme && `(prefers-color-scheme: ${favicon.theme})`}
			/>
		))}

		<!-- Set the theme before the page is rendered to avoid a flash -->
		<script is:inline define:vars={{BANNER_HEIGHT_EXTEND, PAGE_WIDTH, configHue, defaultMode: siteConfig.themeColor.defaultMode ?? "light", defaultWallpaperMode: siteConfig.backgroundWallpaper.mode, isWallpaperSwitchable: siteConfig.backgroundWallpaper.switchable ?? true}}>
			// 主题初始化 - 与setting-utils.ts保持一致
			const LIGHT_MODE = 'light';
			const DARK_MODE = 'dark';
			const SYSTEM_MODE = 'system';
			
			// 获取存储的主题，如果没有则使用默认值
			const theme = localStorage.getItem('theme') || defaultMode;
			
			// 获取系统主题
			function getSystemTheme() {
				return window.matchMedia('(prefers-color-scheme: dark)').matches ? DARK_MODE : LIGHT_MODE;
			}
			
			// 解析主题（如果是system模式，则获取系统主题）
			function resolveTheme(themeValue) {
				if (themeValue === SYSTEM_MODE) {
					return getSystemTheme();
				}
				return themeValue;
			}
			
			const resolvedTheme = resolveTheme(theme);
			const isDark = resolvedTheme === DARK_MODE;
			
			// 应用主题
			if (isDark) {
				document.documentElement.classList.add('dark');
			} else {
				document.documentElement.classList.remove('dark');
			}
			
			// Set the theme for Expressive Code
			document.documentElement.setAttribute("data-theme", isDark ? "github-dark" : "github-light");
			
			// Load the hue from local storage
			const hue = localStorage.getItem('hue') || configHue;
			document.documentElement.style.setProperty('--hue', hue);

			// calculate the --banner-height-extend, which needs to be a multiple of 4 to avoid blurry text
			// 使用更准确的窗口高度计算
			function calculateBannerHeightExtend() {
				let offset = Math.floor(window.innerHeight * (BANNER_HEIGHT_EXTEND / 100));
				offset = offset - offset % 4;
				document.documentElement.style.setProperty('--banner-height-extend', `${offset}px`);
			}
			
			// 立即设置初始值
			calculateBannerHeightExtend();
			
			// 在下一帧重新计算精确值（仅在值变化时更新，避免闪烁）
			requestAnimationFrame(() => {
				const oldValue = parseInt(document.documentElement.style.getPropertyValue('--banner-height-extend'));
				calculateBannerHeightExtend();
				const newValue = parseInt(document.documentElement.style.getPropertyValue('--banner-height-extend'));
				// 如果值变化了，再更新一次确保准确
				if (Math.abs(oldValue - newValue) > 4) {
					// 如果有明显变化，延迟一帧再更新，避免闪烁
					requestAnimationFrame(calculateBannerHeightExtend);
				}
			});

			// 初始化壁纸模式 - 在页面渲染前应用
			const WALLPAPER_BANNER = 'banner';
			const WALLPAPER_OVERLAY = 'overlay';
			const WALLPAPER_NONE = 'none';
			const wallpaperMode = isWallpaperSwitchable ? (localStorage.getItem('wallpaperMode') || defaultWallpaperMode) : defaultWallpaperMode;
			
			// 设置data-wallpaper-mode属性
			document.documentElement.setAttribute('data-wallpaper-mode', wallpaperMode);
			
			// 立即执行函数来处理DOM
			(function applyWallpaperMode() {
				// 使用 requestAnimationFrame 确保在下一帧之前执行
				requestAnimationFrame(function() {
					// 根据模式隐藏显示对应元素
					if (wallpaperMode === WALLPAPER_NONE || wallpaperMode === WALLPAPER_OVERLAY) {
						// 隐藏横幅
						if (document.body) {
							document.body.classList.remove('enable-banner');
							document.body.classList.add('no-banner-layout');
						}
					} else {
						if (document.body) {
							document.body.classList.add('enable-banner');
							document.body.classList.remove('no-banner-layout');
						}
					}
					
					// 全屏壁纸模式
					if (wallpaperMode === WALLPAPER_OVERLAY) {
						if (document.body) {
							document.body.classList.add('wallpaper-transparent');
						}
					} else {
						if (document.body) {
							document.body.classList.remove('wallpaper-transparent');
						}
					}

					// 处理banner和fullscreen wallpaper的显示
					const bannerWrapper = document.getElementById('banner-wrapper');
					const fullscreenWallpaper = document.querySelector('[data-fullscreen-wallpaper]');
					
					// 检查当前是否为首页
					const isHomePage = window.location.pathname === '/' || window.location.pathname === '';
					
					if (wallpaperMode === WALLPAPER_OVERLAY) {
						// 全屏壁纸模式：显示全屏壁纸，隐藏banner
						if (bannerWrapper) {
							bannerWrapper.style.display = 'none';
						}
						if (fullscreenWallpaper) {
							fullscreenWallpaper.style.display = 'block';
							fullscreenWallpaper.classList.remove('hidden', 'opacity-0');
							fullscreenWallpaper.classList.add('opacity-100');
						}
					} else if (wallpaperMode === WALLPAPER_NONE) {
						// 纯色背景：隐藏所有壁纸
						if (bannerWrapper) {
							bannerWrapper.style.display = 'none';
						}
						if (fullscreenWallpaper) {
							fullscreenWallpaper.style.display = 'none';
							fullscreenWallpaper.classList.add('hidden', 'opacity-0');
						}
					} else {
						// banner模式：显示banner，隐藏全屏壁纸
						if (bannerWrapper) {
							bannerWrapper.style.display = 'block';
							// 移动端非首页时隐藏banner
							if (!isHomePage) {
								bannerWrapper.classList.add('mobile-hide-banner');
							} else {
								bannerWrapper.classList.remove('mobile-hide-banner');
							}
						}
						if (fullscreenWallpaper) {
							fullscreenWallpaper.style.display = 'none';
							fullscreenWallpaper.classList.add('hidden', 'opacity-0');
						}
					}
					
					// 处理主内容区域位置
					const mainContentWrapper = document.querySelector('.absolute.w-full.z-30');
					if (mainContentWrapper) {
						if (!isHomePage) {
							mainContentWrapper.classList.add('mobile-main-no-banner');
						} else {
							mainContentWrapper.classList.remove('mobile-main-no-banner');
						}
					}

					// 处理credit元素
					const creditDesktop = document.getElementById('banner-credit-desktop');
					const creditMobile = document.getElementById('banner-credit-mobile');
					if (wallpaperMode === WALLPAPER_OVERLAY || wallpaperMode === WALLPAPER_NONE) {
						if (creditDesktop) creditDesktop.style.display = 'none';
						if (creditMobile) creditMobile.style.display = 'none';
					} else {
						if (creditDesktop) creditDesktop.style.display = '';
						if (creditMobile) creditMobile.style.display = '';
					}

					// 处理banner homeText元素
					const bannerTextOverlay = document.querySelector('.banner-text-overlay');
					if (bannerTextOverlay) {
						const isHomePage = window.location.pathname === '/' || window.location.pathname === '';
						if (wallpaperMode === WALLPAPER_BANNER && isHomePage) {
							bannerTextOverlay.classList.remove('hidden');
						} else {
							bannerTextOverlay.classList.add('hidden');
						}
					}
				});
			})();
		</script>
		<style define:vars={{
			configHue,
			'page-width': `${PAGE_WIDTH}rem`,
		}}></style>  <!-- defines global css variables. This will be applied to <html> <body> and some other elements idk why -->



		<slot name="head"></slot>



		<link rel="alternate" type="application/rss+xml" title={profileConfig.name} href={`${Astro.site}rss.xml`}/>

		
		<!-- Font Manager -->
		<FontManager />

</head>
	<body class=" min-h-screen " class:list={[
		{"lg:is-home": isHomePageCheck, "enable-banner": enableBanner},
		...(siteConfig.font.enable && siteConfig.font.selected ? 
			(Array.isArray(siteConfig.font.selected) 
				? siteConfig.font.selected 
				: [siteConfig.font.selected]
			).map(fontId => `font-${fontId}-enabled`) : [])
	]}>
		<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-KRX3XGVH" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
		
		<!-- 页面顶部渐变高光效果 - 只在full和semifull模式下显示 -->
		{shouldShowTopHighlight && <div class="top-gradient-highlight"></div>}
		<ConfigCarrier></ConfigCarrier>
		<slot />
		
		<!-- Music Player -->
		<MusicPlayer client:load />
		
		<!-- increase the page height during page transition to prevent the scrolling animation from jumping -->
		<div id="page-height-extend" class="hidden h-[300vh]"></div>

		<!-- Sakura Effect -->
		<SakuraEffect />
		
		<!-- Fancybox Manager -->
		<FancyboxManager />
		
	</body>
</html>

<style is:global define:vars={{
	bannerOffset,
	'banner-height-home': `${BANNER_HEIGHT_HOME}vh`,
	'banner-height': `${BANNER_HEIGHT}vh`,
}}>
@tailwind components;
@layer components {
	.enable-banner.is-home #banner-wrapper {
		@apply h-[var(--banner-height-home)] translate-y-[var(--banner-height-extend)]
	}
	.enable-banner #banner-wrapper {
		@apply h-[var(--banner-height-home)]
	}

	.enable-banner.is-home #banner {
		@apply h-[var(--banner-height-home)] translate-y-0
	}
	.enable-banner #banner {
		@apply h-[var(--banner-height-home)] translate-y-[var(--bannerOffset)]
	}
	.enable-banner.is-home #main-grid {
		@apply translate-y-[var(--banner-height-extend)];
	}
	.enable-banner #top-row {
		@apply h-[calc(var(--banner-height-home)_-_4.5rem)] transition-all duration-300
	}
	.enable-banner.is-home #sidebar-sticky {
		@apply top-[calc(1rem_-_var(--banner-height-extend))]
	}
	.navbar-hidden {
		@apply opacity-0 -translate-y-16
	}
}
</style>

<script>
import {getHue, getStoredTheme, setHue, setTheme} from "@/utils/setting-utils";
import {pathsEqual, url} from "@/utils/url-utils";
import {
	BANNER_HEIGHT,
	BANNER_HEIGHT_HOME,
	BANNER_HEIGHT_EXTEND,
	MAIN_PANEL_OVERLAPS_BANNER_HEIGHT
} from "@/constants/constants";
import { siteConfig } from '@/config';

/* Preload fonts */
// (async function() {
// 	try {
// 		await Promise.all([
// 			document.fonts.load("400 1em Roboto"),
// 			document.fonts.load("700 1em Roboto"),
// 		]);
// 		document.body.classList.remove("hidden");
// 	} catch (error) {
// 		console.log("Failed to load fonts:", error);
// 	}
// })();

/* TODO This is a temporary solution for style flicker issue when the transition is activated */
/* issue link: https://github.com/withastro/astro/issues/8711, the solution get from here too */
/* update: fixed in Astro 3.2.4 */
/*
function disableAnimation() {
	const css = document.createElement('style')
	css.appendChild(
		document.createTextNode(
			`*{
              -webkit-transition:none!important;
              -moz-transition:none!important;
              -o-transition:none!important;
              -ms-transition:none!important;
              transition:none!important
              }`
		)
	)
	document.head.appendChild(css)

	return () => {
		// Force restyle
		;(() => window.getComputedStyle(document.body))()

		// Wait for next tick before removing
		setTimeout(() => {
			document.head.removeChild(css)
		}, 1)
	}
}
*/

const bannerEnabled = !!document.getElementById('banner-wrapper')

function setClickOutsideToClose(panel: string, ignores: string[]) {
	document.addEventListener("click", event => {
		let panelDom = document.getElementById(panel);
		let tDom = event.target;
		if (!(tDom instanceof Node)) return;		// Ensure the event target is an HTML Node
		for (let ig of ignores) {
			let ie = document.getElementById(ig)
			if (ie == tDom || (ie?.contains(tDom))) {
				return;
			}
		}
		panelDom!.classList.add("float-panel-closed");
	});
}
setClickOutsideToClose("display-setting", ["display-setting", "display-settings-switch"])
setClickOutsideToClose("nav-menu-panel", ["nav-menu-panel", "nav-menu-switch"])
setClickOutsideToClose("search-panel", ["search-panel", "search-bar", "search-switch"])
setClickOutsideToClose("wallpaper-mode-panel", ["wallpaper-mode-panel", "wallpaper-mode-switch"])
setClickOutsideToClose("theme-mode-panel", ["theme-mode-panel", "scheme-switch"])


function loadTheme() {
	const theme = getStoredTheme()
	setTheme(theme)
}

function loadHue() {
	setHue(getHue())
}

function initCustomScrollbar() {
	// 只处理katex元素的滚动条，使用浏览器原生滚动条
	const katexElements = document.querySelectorAll('.katex-display:not([data-scrollbar-initialized])') as NodeListOf<HTMLElement>;
	katexElements.forEach(element => {
		if (!element.parentNode) return;

		const container = document.createElement('div');
		container.className = 'katex-display-container';
		element.parentNode.insertBefore(container, element);
		container.appendChild(element);

		// 使用浏览器原生滚动条，无自定义样式
		container.style.cssText = `
			overflow-x: auto;
		`;

		element.setAttribute('data-scrollbar-initialized', 'true');
	});
}

function showBanner() {
	const isBannerMode = siteConfig.backgroundWallpaper.mode === "banner";
	if (!isBannerMode) return;

	// 使用requestAnimationFrame优化DOM操作
	requestAnimationFrame(() => {
		// Handle single image banner (desktop)
		const banner = document.getElementById('banner');
		if (banner) {
			banner.classList.remove('opacity-0', 'scale-105');
		}

		// Handle mobile single image banner - 使用与电脑端相同的逻辑
		const mobileBanner = document.querySelector('.block.lg\\:hidden[alt="Mobile banner image of the blog"]');
		if (mobileBanner) {
			// 移动端使用与电脑端相同的初始化逻辑
			mobileBanner.classList.remove('opacity-0', 'scale-105');
			mobileBanner.classList.add('opacity-100');
		}

	});
}



const setup = () => {
	// TODO: temp solution to change the height of the banner
/*
	window.swup.hooks.on('animation:out:start', () => {
		const path = window.location.pathname
		const body = document.querySelector('body')
		if (path[path.length - 1] === '/' && !body.classList.contains('is-home')) {
			body.classList.add('is-home')
		} else if (path[path.length - 1] !== '/' && body.classList.contains('is-home')) {
			body.classList.remove('is-home')
		}
	})
*/
	window.swup.hooks.on('link:click', () => {
		// Remove the delay for the first time page load
		document.documentElement.style.setProperty('--content-delay', '0ms')

		// 添加页面切换保护，防止导航栏闪烁
		document.documentElement.classList.add('is-page-transitioning')

		// 简化navbar处理逻辑
		if (bannerEnabled) {
			const navbar = document.getElementById('navbar-wrapper')
			if (navbar && document.body.classList.contains('lg:is-home')) {
				const threshold = window.innerHeight * (BANNER_HEIGHT / 100) - 88
				if (document.documentElement.scrollTop >= threshold) {
					navbar.classList.add('navbar-hidden')
				}
			}
		}
	})
	window.swup.hooks.on('content:replace', () => {
		// 只处理katex元素的容器，使用浏览器原生滚动条
		initCustomScrollbar();
		
		// 检查当前页面是否为文章页面（有TOC元素）
		const tocWrapper = document.getElementById('toc-wrapper');
		const isArticlePage = tocWrapper !== null;
		
		// 只在文章页面重新初始化桌面端 TOC 组件
		if (isArticlePage) {
			const tocElement = document.querySelector('table-of-contents');
			if (tocElement && typeof (tocElement as any).init === 'function') {
				setTimeout(() => {
					(tocElement as any).init();
				}, 100);
			}
		}
		
		// 移动端 TOC 组件需要在所有页面都重新初始化
		// 因为它在首页显示文章列表，在其他页面显示目录
		if (typeof (window as any).mobileTOCInit === 'function') {
			setTimeout(() => {
				(window as any).mobileTOCInit();
			}, 100);
		}
		
		
		
		// 重新初始化semifull模式的滚动检测
		const navbar = document.getElementById('navbar')
		if (navbar) {
			const transparentMode = navbar.getAttribute('data-transparent-mode')
			
			if (transparentMode === 'semifull') {
				// 重新调用初始化函数来重新绑定滚动事件
				if (typeof (window as any).initSemifullScrollDetection === 'function') {
					(window as any).initSemifullScrollDetection()
				}
			}
		}
	})
	window.swup.hooks.on('visit:start', (visit: {to: {url: string}}) => {
		// change banner height immediately when a link is clicked
		const bodyElement = document.querySelector('body')
		const isHomePage = pathsEqual(visit.to.url, url('/'))
		
		if (isHomePage) {
			bodyElement!.classList.add('lg:is-home');
		} else {
			bodyElement!.classList.remove('lg:is-home');
		}

		// Control banner text visibility based on page
		const bannerTextOverlay = document.querySelector('.banner-text-overlay')
		if (bannerTextOverlay) {
			if (isHomePage) {
				bannerTextOverlay.classList.remove('hidden')
			} else {
				bannerTextOverlay.classList.add('hidden')
			}
		}

		// Control navbar transparency based on page
		const navbar = document.getElementById('navbar')
		if (navbar) {
			navbar.setAttribute('data-is-home', isHomePage.toString())
			
			// 重新初始化semifull模式的滚动检测
			const transparentMode = navbar.getAttribute('data-transparent-mode')
			if (transparentMode === 'semifull') {
				// 重新调用初始化函数来重新绑定滚动事件
				if (typeof (window as any).initSemifullScrollDetection === 'function') {
					(window as any).initSemifullScrollDetection()
				}
			}
		}

		// Control mobile banner visibility based on page with improved staging animation
		const bannerWrapper = document.getElementById('banner-wrapper')
		const mainContentWrapper = document.querySelector('.absolute.w-full.z-30')
		
		if (bannerWrapper && mainContentWrapper) {
			if (isHomePage) {
				// 首页：延迟移除隐藏类，让banner和内容优雅地出现
				setTimeout(() => {
					bannerWrapper.classList.remove('mobile-hide-banner')
				}, 100)
				setTimeout(() => {
					mainContentWrapper.classList.remove('mobile-main-no-banner')
				}, 150)
			} else {
				// 非首页：分阶段隐藏，先隐藏banner，再移动内容
				bannerWrapper.classList.add('mobile-hide-banner')
				// 延迟移动内容，让banner先完全消失
				setTimeout(() => {
					mainContentWrapper.classList.add('mobile-main-no-banner')
				}, 100)
			}
		}

		// increase the page height during page transition to prevent the scrolling animation from jumping
		const heightExtend = document.getElementById('page-height-extend')
		if (heightExtend) {
			heightExtend.classList.remove('hidden')
		}

		// Hide the TOC while scrolling back to top
		let toc = document.getElementById('toc-wrapper');
		if (toc) {
			toc.classList.add('toc-not-ready')
		}
	});
	window.swup.hooks.on('page:view', () => {
		// hide the temp high element when the transition is done
		const heightExtend = document.getElementById('page-height-extend')
		if (heightExtend) {
			heightExtend.classList.remove('hidden')
		}
		
		// 确保页面滚动到顶部，特别是移动端banner关闭时
		window.scrollTo({
			top: 0,
			behavior: 'instant'
		});
		
		// 同步主题状态 - 解决从首页进入文章页面时代码块渲染问题
		const storedTheme = localStorage.getItem('theme') || 'light';
		const isDark = storedTheme === 'dark';
		const expectedTheme = isDark ? 'github-dark' : 'github-light';
		const currentTheme = document.documentElement.getAttribute('data-theme');
		
		// 如果主题不匹配，强制重新应用
		if (currentTheme !== expectedTheme) {
			document.documentElement.setAttribute('data-theme', expectedTheme);
			// 触发代码块重新渲染
			setTimeout(() => {
				window.dispatchEvent(new CustomEvent('theme-change'));
			}, 50);
		}
		
		// 检查当前页面是否为文章页面，如果是则触发自定义事件用于初始化评论系统
		setTimeout(() => {
			if (document.getElementById('tcomment')) {
				// 触发自定义事件，通知评论系统页面已完全加载
				const pageLoadedEvent = new CustomEvent('firefly:page:loaded', {
					detail: {
						path: window.location.pathname,
						timestamp: Date.now()
					}
				});
				document.dispatchEvent(pageLoadedEvent);
				console.log('Layout: 触发 firefly:page:loaded 事件，路径:', window.location.pathname);
			}
		}, 300);
	});
	window.swup.hooks.on('visit:end', (_visit: {to: {url: string}}) => {
		setTimeout(() => {
			const heightExtend = document.getElementById('page-height-extend')
			if (heightExtend) {
				heightExtend.classList.add('hidden')
			}

            // Just make the transition looks better
            const toc = document.getElementById('toc-wrapper');
            if (toc) {
                toc.classList.remove('toc-not-ready')
            }
            
            // 移除页面切换保护，恢复过渡动画
            document.documentElement.classList.remove('is-page-transitioning')
        }, 200)
	});
}
if (window?.swup?.hooks) {
	setup()
} else {
	document.addEventListener('swup:enable', setup)
}

let backToTopBtn = document.getElementById('back-to-top-btn');
let toc = document.getElementById('toc-wrapper');
let navbar = document.getElementById('navbar-wrapper')

// 优化的滚动处理函数
function scrollFunction() {
	const scrollTop = document.documentElement.scrollTop;
	const bannerHeight = window.innerHeight * (BANNER_HEIGHT / 100);

	// 使用批量DOM操作优化性能
	const operations = [];
	
	if (backToTopBtn) {
		operations.push(() => {
			if (scrollTop > bannerHeight) {
				backToTopBtn.classList.remove('hide')
			} else {
				backToTopBtn.classList.add('hide')
			}
		});
	}

	if (bannerEnabled && toc) {
		operations.push(() => {
			if (scrollTop > bannerHeight) {
				toc.classList.remove('toc-hide')
			} else {
				toc.classList.add('toc-hide')
			}
		});
	}

	if (bannerEnabled && navbar) {
		operations.push(() => {
			const isHome = document.body.classList.contains('lg:is-home') && window.innerWidth >= 1024;
			const currentBannerHeight = isHome ? BANNER_HEIGHT_HOME : BANNER_HEIGHT;
			const threshold = window.innerHeight * (currentBannerHeight / 100) - 88;
			
			if (scrollTop >= threshold) {
				navbar.classList.add('navbar-hidden')
			} else {
				navbar.classList.remove('navbar-hidden')
			}
		});
	}

	// 批量执行DOM操作
	if (operations.length > 0) {
		requestAnimationFrame(() => {
			operations.forEach(op => op());
		});
	}
}

// 使用优化的滚动性能处理
let scrollTimeout: number;
window.addEventListener('scroll', () => {
	if (scrollTimeout) {
		cancelAnimationFrame(scrollTimeout);
	}
	scrollTimeout = requestAnimationFrame(scrollFunction);
}, { passive: true });

window.onresize = () => {
	// calculate the --banner-height-extend, which needs to be a multiple of 4 to avoid blurry text
	let offset = Math.floor(window.innerHeight * (BANNER_HEIGHT_EXTEND / 100));
	offset = offset - offset % 4;
	document.documentElement.style.setProperty('--banner-height-extend', `${offset}px`);
}

// 页面加载完成后初始化banner和katex容器
if (document.readyState === 'loading') {
	document.addEventListener('DOMContentLoaded', () => {
		showBanner();
		initCustomScrollbar();
	});
} else {
	showBanner();
	initCustomScrollbar();
}

// Initialize wallpaper mode
import { initWallpaperMode, initThemeListener } from '@/utils/setting-utils';
if (document.readyState === 'loading') {
	document.addEventListener('DOMContentLoaded', () => {
		initWallpaperMode();
		initThemeListener();
	});
} else {
	initWallpaperMode();
	initThemeListener();
}

</script>


